package io.finer.erp.jeecg.bas.service.impl;

import io.finer.erp.jeecg.bas.dto.FqDTO;
import io.finer.erp.jeecg.bas.entity.BasMaterial;
import io.finer.erp.jeecg.bas.entity.CreateCuttingParams;
import io.finer.erp.jeecg.bas.entity.CuttingMethod;
import io.finer.erp.jeecg.bas.entity.ZrkCutting;
import io.finer.erp.jeecg.bas.entity.ZrkFqjf;
import io.finer.erp.jeecg.bas.entity.ZrkQzOrdeDetail;
import io.finer.erp.jeecg.bas.mapper.ZrkCuttingDetailMapper;
import io.finer.erp.jeecg.bas.mapper.ZrkCuttingMapper;
import io.finer.erp.jeecg.bas.service.IBasMaterialService;
import io.finer.erp.jeecg.bas.service.IZrkCuttingDetailService;
import io.finer.erp.jeecg.bas.service.IZrkCuttingService;
import io.finer.erp.jeecg.bas.service.IZrkFqjfService;
import io.finer.erp.jeecg.bas.service.IZrkQzOrdeDetailService;
import io.finer.erp.jeecg.bas.util.GetCuttingMethod;
import io.finer.erp.jeecg.stock.entity.StkInventory;
import io.finer.erp.jeecg.stock.service.IStkInventoryService;

import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.api.client.util.Maps;
import com.google.common.collect.Lists;

import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.TestDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;

/**
 * @Description: 智能分切
 * @Author: jeecg-boot
 * @Date:   2020-08-25
 * @Version: V1.0
 */
@Service
public class ZrkCuttingServiceImpl extends ServiceImpl<ZrkCuttingMapper, ZrkCutting> implements IZrkCuttingService {

	@Autowired
	private ZrkCuttingMapper zrkCuttingMapper;
	@Autowired
	private ZrkCuttingDetailMapper zrkCuttingDetailMapper;
	@Autowired
	private IZrkFqjfService zrkFqjfService;
	@Autowired
	private IStkInventoryService stkInventoryService;
	@Autowired
	private IBasMaterialService materialService;
	@Autowired
	private IZrkCuttingDetailService detailService;
	@Autowired
	private IZrkQzOrdeDetailService qzOrderDetailService;
	
	@Override
	@Transactional
	public void delMain(String id) {
		zrkCuttingDetailMapper.deleteByMainId(id);
		zrkCuttingMapper.deleteById(id);
	}

	@Override
	@Transactional
	public void delBatchMain(Collection<? extends Serializable> idList) {
		for(Serializable id:idList) {
			zrkCuttingDetailMapper.deleteByMainId(id.toString());
			zrkCuttingMapper.deleteById(id);
		}
	}

	/**
	 * @Description: 创建分切方案
	 * @param cutting
	 * @return
	 * Create at: 2020-09-10 10:56:34
	 * @author: duanyong
	 * Revision:
	 *    2020-09-10 10:56:34 - first revision by duanyong
	 *        
	 */
	@Override
	public Result<Object> createCutting(ZrkCutting cutting) {
    	Result<Object> result = new Result<>();
    	Integer length = cutting.getLength();
    	if (null == length) {
    		return Result.error("请输入长度");
    	}
    	BigDecimal lengthDecimal = new BigDecimal(length.intValue());
    	String expression = cutting.getExpression();
    	Map<String, Object> expressionsMap =  getExpressions(expression);
    	BigDecimal[] expressions = (BigDecimal[])expressionsMap.get("bigDecimalArr");
//    	String[] expressionStringArr = (String[])expressionsMap.get("strArr");
    	BigDecimal totalWidth = BigDecimal.ZERO;
    	for (int i = 0; i < expressions.length; i++) {
			totalWidth = totalWidth.add(expressions[i]);
		}
    	//为宽度排序
    	Arrays.sort(expressions, (ex1, ex2) -> ex1.compareTo(ex2));
    	
    	
    	int ds=0;
    	//设置分切刀数、调刀数
    	Map<String,Object> columnMap=new HashMap<String,Object>();
    	columnMap.put("machine_type", cutting.getFqJq());
    	Collection<ZrkFqjf> zrkFqjfCollection = zrkFqjfService.listByMap(columnMap);
    	if(null!=zrkFqjfCollection&&zrkFqjfCollection.size()>0) {
    		Iterator<ZrkFqjf> iterator=zrkFqjfCollection.iterator();
    		while(iterator.hasNext()) {
    			ZrkFqjf fqjf=iterator.next();
    			ds=cutting.getZrkDs()/Integer.parseInt(fqjf.getPerMetre());
    			break;
    		}
    		cutting.setZrkDs(ds);
    		cutting.setZrkTds(1);
    	}
    	//添加分切记录时,自动提供分切方案并记录(以先进先出为原则)
//    	String materialId = cutting.getMaterialId();//原材料编号
    	//根据物料编号查询之前的老料信息
//    	if (!StringUtils.isBlank(materialId)) {
//    		BasMaterial material = this.materialService.getById(materialId);
//    		if (material == null) {
//    			return result.error500("没有该物料的记录");
//    		}
//    		Map<String,Object> columnOldMap=new HashMap<String,Object>();
//        	columnOldMap.put("material_id", materialId);
//        	Collection<StkInventory> inventoryCollection = stkInventoryService.listByMap(columnOldMap);
//        	if(null == inventoryCollection || 0 == inventoryCollection.size()) {
//        		return result.error500("库存中未找到该物料");
//        	}
//        	StkInventory inventory = inventoryCollection.iterator().next();
//        	BigDecimal amount = inventory.getQty();
//        	if (amount.compareTo(lengthDecimal) < 0) {
//        		return result.error500("所选物料库存不足");
//        	}
//        	BigDecimal width = material.getWidth();
//        	if (totalWidth.compareTo(width) > 0) {
//        		return result.error500("该物料宽度不够");
//        	}
//        	
//        	this.save(cutting);
//        	ZrkCuttingDetail detail = new ZrkCuttingDetail();
//        	detail.setBasMaertialId(materialId);
//        	detail.setIsSelected("0");
//        	detail.setBasMaterialName(material.getName());
//        	detail.setCreateBy(cutting.getCreateBy());
//        	detail.setCreateTime(cutting.getCreateTime());
//        	detail.setZrkTds("1");
//        	detail.setZrkDs(cutting.getZrkDs().toString());
//        	detail.setMethodName(material.getName() + "分切方案");
//        	detail.setZrkCuttingId(cutting.getId());
//        	detail.setBasCangku(inventory.getWarehouseId());
//        	detail.setBasMaertialId(materialId);
//        	this.detailService.save(detail);
//        	return result.success("添加成功");
//    	}
    	
    	
    	//根据物料分类查找库存,出智能分切方案
    	//计算库存物料平方数
    	Integer width = cutting.getMaterialWidth();
    	String materialType = cutting.getBasMaterialType();
    	BigDecimal mTotalSquare = BigDecimal.ZERO;
    	BigDecimal cuttingSquare = totalWidth.multiply(lengthDecimal.multiply(new BigDecimal(100)));
    	LambdaQueryWrapper<BasMaterial> mateQuery = new LambdaQueryWrapper<>();
    	mateQuery.eq(BasMaterial::getCategoryId, materialType);
    	mateQuery.gt(BasMaterial::getWidth, expressions[0]);//比最小宽度还小的物料不显示
//    	mateQuery.eq(BasMaterial::getWidth, width);//输入根据宽度取出物料
    	List<BasMaterial> materialList = this.materialService.list(mateQuery);
    	Map<String, BasMaterial> mateMap = new HashMap<>();
    	List<String> materialIdList = Lists.newArrayList();//查询库存的查询条件
    	for (BasMaterial basMaterial : materialList) {
			BigDecimal mWidth = basMaterial.getWidth();
			BigDecimal mLength = basMaterial.getLength();
			mTotalSquare = mTotalSquare.add(mWidth.multiply(mLength));
			mateMap.put(basMaterial.getId(), basMaterial);
			materialIdList.add(basMaterial.getId());
		}
    	//如果库存物料的平方数不足
    	if (mTotalSquare.compareTo(cuttingSquare) < 0) {
    		return result.error500("库存物料的平方数不足，请采购");
    	}
    	//查找物料库存
    	LambdaQueryWrapper<StkInventory> invenQuery = new LambdaQueryWrapper<>();
    	invenQuery.in(StkInventory::getMaterialId, materialIdList);
    	invenQuery.gt(StkInventory::getQty, 0);
    	invenQuery.eq(StkInventory::getIsClosed, 0);
    	List<StkInventory> inventoryList = this.stkInventoryService.list(invenQuery);
    	//库存中没有该分类的物料
    	if (inventoryList == null || inventoryList.size() == 0) {
    		return result.error500("物料库存不足，请采购");
    	}
    	//计算库存物料的长度是否足够
    	BigDecimal mTotalLength = BigDecimal.ZERO;
    	List<String> mIdList = Lists.newArrayList();
    	for (StkInventory stkInventory : inventoryList) {
    		mTotalLength = mTotalLength.add(stkInventory.getQty());
    		mIdList.add(stkInventory.getMaterialId());
		}
    	//如果库存物料不足
    	if (mTotalLength.compareTo(lengthDecimal) < 0) {
    		return result.error500("物料库存不足，请采购");
    	}
    	
    	//计算并实现分切方案
    	List<TestDTO> dtoList = Lists.newArrayList();
    	for (StkInventory stkInventory : inventoryList) {
    		String mateId = stkInventory.getMaterialId();
    		BasMaterial mate = mateMap.get(mateId);
    		//库存与物料匹配
    		if (null != mate) {
    			TestDTO dto = TestDTO.builder().id(mateId).num(stkInventory.getQty().intValue()).width(mate.getWidth()).build();
        		dtoList.add(dto);
    		}
		}
    	List<CuttingMethod> methodList = GetCuttingMethod.getCuttingMethod(length, dtoList, expressions, width);
    	
    	
    	//如果原料不足，查询物料分类下的物料库存
		return null;
	}
	
	
    /**
     * @Description 获取分切物料宽度的集合
     * @param expression
     * @return
     * Create at: 2020-09-10 10:55:54
     * @author: duanyong
     * Revision:
     *    2020-09-10 10:55:54 - first revision by duanyong
     *        
     */
    private Map<String, Object> getExpressions(String expression) {
    	String[] strings = StringUtils.split(expression, "\\+");
    	Map<String, Object> map = new HashMap<>();
    	map.put("strArr", strings);
    	BigDecimal[] result = new BigDecimal[strings.length];
    	for (int i = 0; i < strings.length; i++) {
    		result[i] = new BigDecimal(strings[i]);
		}
    	map.put("bigDecimalArr", result);
    	return map;
    }

	@Override
	public Result<Object> createCuttingMethod(CreateCuttingParams param, String zrkQzOrderId) {
		Result<Object> result = new Result<>();
		// TODO Auto-generated method stub
		String fqCategory = param.getFqCategory();
		String fqParam = param.getFqParam();
		Integer fqLength = param.getFqLength();
//		String paperSupplier = param.getPaperSupplier();
//		String glueSupplier = param.getGlueSupplier();
		List<String> supplierMateList = Lists.newArrayList();
		boolean supplierFlag = false;
		//TODO 这里应该取交集后期记得处理
//		if(StringUtils.isNotBlank(glueSupplier)) {
//			supplierMateList.addAll(this.getSuplierMaterialId(glueSupplier, fqCategory));
//			supplierFlag = true;
//		}
//		if(StringUtils.isNotBlank(paperSupplier)) {
//			supplierMateList.addAll(this.getSuplierMaterialId(paperSupplier, fqCategory));
//			supplierFlag = true;
//		}
		
		BigDecimal lengthDecimal = new BigDecimal(fqLength.intValue());
    	Map<String, Object> expressionsMap =  getExpressions(fqParam);
    	BigDecimal[] expressions = (BigDecimal[])expressionsMap.get("bigDecimalArr");
//    	String[] expressionStringArr = (String[])expressionsMap.get("strArr");
//    	BigDecimal totalWidth = BigDecimal.ZERO;
//    	for (int i = 0; i < expressions.length; i++) {
//			totalWidth = totalWidth.add(expressions[i]);
//		}
//    	//为宽度排序
//    	Arrays.sort(expressions, (ex1, ex2) -> ex1.compareTo(ex2));
    	int num = 1;
    	Map<Integer, List<FqDTO>> fqMap = Maps.newLinkedHashMap();
    	for (int i = 0; i < expressions.length; i++) {
    		BigDecimal expression = expressions[i];
    		List<FqDTO> list = this.stkInventoryService.getFqParameter(expression, lengthDecimal, fqCategory);
    		if(list == null || list.size() == 0) {
    			return Result.error("没有合适的物料");
    		}
    		fqMap.put(new Integer(num), list);
    		num ++;
		}
    	List<FqDTO> firstList = null;
    	List<FqDTO> secondList = null;
    	List<FqDTO> thirdList = null;
    	Random random = new Random();
    	for(int i = 0; i < 2000; i++) {
    		if(firstList != null && secondList != null && thirdList != null) {
    			break;
    		}
    		List<FqDTO> newList = Lists.newArrayList();
    		for(Integer key: fqMap.keySet()) {
        		List<FqDTO> list = fqMap.get(key);
        		int index = random.nextInt(list.size());
        		FqDTO fqDTO = list.get(index);
        		if(newList.contains(fqDTO)) {
        			break;
        		} else {
        			newList.add(fqDTO);
        		}
        	}
    		if(newList.size() == expressions.length) {
    			if(firstList == null) {
    				firstList = newList;
    				continue;
    			}
    			if(secondList == null) {
    				secondList = newList;
    				continue;
    			}
    			if(thirdList == null) {
    				thirdList = newList;
    				continue;
    			}
    		}
    	}
    	if(firstList != null && firstList.size() > 0) {
    		for (FqDTO fqDTO : firstList) {
    			BasMaterial material = materialService.getById(fqDTO.getMaterialId());
    			ZrkQzOrdeDetail detail = ZrkQzOrdeDetail.builder().kuan(fqDTO.getWidth().toString())
    					.chang(fqDTO.getLength().toString()).createTime(DateUtils.gettimestamp())
    					.basCangku(fqDTO.getWarehouseId()).zrkQzOrderId(zrkQzOrderId)
    					.detailName("方案1(推荐)").materialId(fqDTO.getMaterialId())
    					.supplierId(fqDTO.getSupplierId()).materialCode(material.getCode()).build();
    			this.qzOrderDetailService.save(detail);
    		}
    	} else {
    		return Result.error("未找到分切方案");
    	}
    	if(secondList != null && secondList.size() != 0) {
    		for (FqDTO fqDTO : secondList) {
    			BasMaterial material = materialService.getById(fqDTO.getMaterialId());
    			ZrkQzOrdeDetail detail = ZrkQzOrdeDetail.builder().kuan(fqDTO.getWidth().toString())
    					.chang(fqDTO.getLength().toString()).createTime(DateUtils.gettimestamp())
    					.basCangku(fqDTO.getWarehouseId()).zrkQzOrderId(zrkQzOrderId)
    					.detailName("方案2").materialId(fqDTO.getMaterialId()).materialCode(material.getCode())
    					.supplierId(fqDTO.getSupplierId()).build();
    			this.qzOrderDetailService.save(detail);
    		}
    	} else {
    		return Result.ok();
    	}
    	if(thirdList != null && thirdList.size() != 0) {
    		for (FqDTO fqDTO : thirdList) {
    			BasMaterial material = materialService.getById(fqDTO.getMaterialId());
    			ZrkQzOrdeDetail detail = ZrkQzOrdeDetail.builder().kuan(fqDTO.getWidth().toString())
    					.chang(fqDTO.getLength().toString()).createTime(DateUtils.gettimestamp())
    					.basCangku(fqDTO.getWarehouseId()).zrkQzOrderId(zrkQzOrderId)
    					.detailName("方案3").materialId(fqDTO.getMaterialId()).materialCode(material.getCode())
    					.supplierId(fqDTO.getSupplierId()).build();
    			this.qzOrderDetailService.save(detail);
    		}
    	} else {
    		return Result.ok();
    	}
    	
    	
    	//根据物料分类查找库存,出智能分切方案
    	//计算库存物料平方数
//    	Integer width = cutting.getMaterialWidth();
//    	BigDecimal mTotalSquare = BigDecimal.ZERO;
//    	BigDecimal cuttingSquare = totalWidth.multiply(lengthDecimal.multiply(new BigDecimal(100)));
//    	LambdaQueryWrapper<BasMaterial> mateQuery = new LambdaQueryWrapper<>();
//    	mateQuery.eq(BasMaterial::getCategoryId, fqCategory);
//    	mateQuery.gt(BasMaterial::getWidth, expressions[0]);//比最小宽度还小的物料不需要
//    	mateQuery.orderByAsc(BasMaterial::getCreateTime);
//    	
//    	//取出对应供应商的产品
//    	if(supplierFlag && supplierMateList.size() != 0) {
//    		mateQuery.in(BasMaterial::getId, supplierMateList);
//    	} else {
//    		return result.error500("现阶段没有该供应商对应的物料");
//    	}
//    	List<BasMaterial> materialList = this.materialService.list(mateQuery);
//    	Map<String, BasMaterial> mateMap = new HashMap<>();
//    	List<String> materialIdList = Lists.newArrayList();//查询库存的查询条件
//    	for (BasMaterial basMaterial : materialList) {
//			BigDecimal mWidth = basMaterial.getWidth();
//			BigDecimal mLength = basMaterial.getLength();
//			mTotalSquare = mTotalSquare.add(mWidth.multiply(mLength));
//			mateMap.put(basMaterial.getId(), basMaterial);
//			materialIdList.add(basMaterial.getId());
//		}
//    	//如果库存物料的平方数不足
//    	if (mTotalSquare.compareTo(cuttingSquare) < 0) {
//    		return result.error500("库存物料的平方数不足，请采购");
//    	}
//    	//查找物料库存
//    	LambdaQueryWrapper<StkInventory> invenQuery = new LambdaQueryWrapper<>();
//    	invenQuery.in(StkInventory::getMaterialId, mateMap.keySet());
//    	invenQuery.gt(StkInventory::getQty, 0);
//    	invenQuery.eq(StkInventory::getIsClosed, 0);
//    	List<StkInventory> inventoryList = this.stkInventoryService.list(invenQuery);
//    	//库存中没有该分类的物料
//    	if (inventoryList == null || inventoryList.size() == 0) {
//    		return result.error500("物料库存不足，请采购");
//    	}
//    	//计算库存物料的长度是否足够
//    	BigDecimal mTotalLength = BigDecimal.ZERO;
//    	List<String> mIdList = Lists.newArrayList();
//    	for (StkInventory stkInventory : inventoryList) {
//    		mTotalLength = mTotalLength.add(stkInventory.getQty());
//    		mIdList.add(stkInventory.getMaterialId());
//		}
//    	//如果库存物料不足
//    	if (mTotalLength.compareTo(lengthDecimal) < 0) {
//    		return result.error500("物料库存不足，请采购");
//    	}
    	
    	//计算并实现分切方案
//    	List<TestDTO> dtoList = Lists.newArrayList();
//    	for (StkInventory stkInventory : inventoryList) {
//    		String mateId = stkInventory.getMaterialId();
//    		BasMaterial mate = mateMap.get(mateId);
//    		//库存与物料匹配
//    		if (null != mate) {
//    			TestDTO dto = TestDTO.builder().id(mateId).num(stkInventory.getQty().intValue()).width(mate.getWidth()).build();
//        		dtoList.add(dto);
//    		}
//		}
//    	List<CuttingMethod> methodList = GetCuttingMethod.getCuttingMethod(fqLength, dtoList, expressions, 0);
//    	for (CuttingMethod cuttingMethod : methodList) {
//    		
//		}
		return Result.error("未生成");
	}
	
	private List<String> getSuplierMaterialId(String suplierId, String fqCategory){
		return this.materialService.getSuplierMaterialId(suplierId, fqCategory);
	}
	
	private List<BasMaterial> getMaterials(BigDecimal width, BigDecimal length, String categoryId){
		
		return null;
	}

	@Override
	public void deleteByMainId(String id) {
		LambdaQueryWrapper<ZrkQzOrdeDetail> delete = new LambdaQueryWrapper<>();
		delete.eq(ZrkQzOrdeDetail::getZrkQzOrderId, id);
		qzOrderDetailService.remove(delete);
	}
}
